// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
#include "pch.h"
#include "DataModel\ForecastManager.h"
#include "LocationData.h"

using namespace Weathr;

using namespace concurrency;
using namespace Platform;
using namespace std;
using namespace web;
using namespace Windows::ApplicationModel;
using namespace Windows::Storage;

LocationData& LocationData::Current()
{
    static LocationData instance;
    return instance;
}

String^ AppLocationsDataFile = R"(DataModel\Locations.json)";
String^ LocationDataDataFile = "LocationData.json";

LocationData::LocationData() : m_appLocationsFileReaderWriter(Package::Current->InstalledLocation, AppLocationsDataFile, CreationCollisionOption::ReplaceExisting)
    , m_userLocationsFileReaderWriter(ApplicationData::Current->LocalFolder, LocationDataDataFile, CreationCollisionOption::ReplaceExisting)
{
    m_appLocationsFileReaderWriter.start();
    m_userLocationsFileReaderWriter.start();
}

// Reads the provided collection of locations from disk.
task<json::value> LoadLocationsAsync(FileReaderWriter& reader)
{
    return reader.ReadAsync({}).then([](String^ jsonText)
    {
        assert(IsBackgroundThread());
        return json::value::parse(wstring(jsonText->Data(), jsonText->Length()));
    });
}

// Reads the collection pre-defined app locations from disk.
task<json::value> LocationData::LoadAppLocationsAsync()
{
    return LoadLocationsAsync(m_appLocationsFileReaderWriter);
}

// Reads the collection user-defined locations from disk.
task<json::value> LocationData::LoadUserLocationsAsync()
{
    // User locations are held in the app data store.
    return LoadLocationsAsync(m_userLocationsFileReaderWriter);
}

// Writes the collection of user-defined locations to disk.
task<void> LocationData::SaveUserLocationsAsync()
{
    // Form JSON data and save to disk.

    wstring endElement;
    wostringstream ss;
    ss << L'{' << endl;
    ss << L"    \"locations\":[" << endl;
    for (auto group : ForecastManager::Current->ForecastGroups)
    {
        for (auto forecast : group->Items)
        {
            ss << endElement;
            if (endElement.length() == 0)
            {
                wostringstream temp;
                temp << L"    }," << endl;
                endElement = temp.str();
            }
            ss << L"    {" << endl;
            ss << L"        \"locality\":\"" << forecast->Locality->Data() << L"\"," << endl;
            ss << L"        \"adminDistrict\":\"" << forecast->AdminDistrict->Data() << L"\"," << endl;
            ss << L"        \"countryRegion\":\"" << forecast->CountryRegion->Data() << L"\"," << endl;
            ss << L"        \"latitude\":" << forecast->Latitude << L"," << endl;
            ss << L"        \"longitude\":" << forecast->Longitude << endl;
        }
    }
    ss << L"    }" << endl;
    ss << L"    ]" << endl;
    ss << L'}' << endl;
    auto content = ref new String(ss.str().c_str());

    return m_userLocationsFileReaderWriter.WriteAsync(content);
}
